/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       window_clip_list.h

	$Header: /game/window_clip_list.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef WINDOW_CLIP_LIST_H_INCLUDED
#define WINDOW_CLIP_LIST_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#pragma warning( disable: 4786 )

#include <list>
#include "window_rect.h"

class t_clip_list;
// ---------------------------------------------------------------
// object to maintain a list of valid rectangles for drawing
// ---------------------------------------------------------------
class t_window_clip_list
{
public:
	typedef std::list<t_window_rect>::iterator       t_iterator;
	typedef std::list<t_window_rect>::const_iterator t_const_iterator;

	t_window_clip_list();
	t_window_clip_list( t_window_rect const& rect );

	template<class iterator>
	t_window_clip_list( iterator first, iterator last  )
	{
		while (first != last)
		{
			m_rects.push_back( *first );
			first++;
		}
		update_extent();
	}
	void                 add( t_clip_list& regions, t_window* window );
	t_iterator           begin();        // get start of list
	t_const_iterator     begin() const;
	void                 clear();
	bool                 contains( t_screen_rect const& rect ) const;
	bool                 empty() const;
	t_iterator           end();          // get end of list
	t_const_iterator     end() const;
	t_screen_rect const& get_extent() const;
	void                 intersect( t_screen_rect const& rect ); // remove non-intersecting regions
	void                 intersect( t_clip_list const& regions );
	bool                 intersects( t_screen_rect const& rect ) const;
	void                 merge_rectangles();                     // attempt to merge 1st rect
	void                 offset( t_screen_point const& point );  // move entire region

	t_window_clip_list& operator -= (t_screen_rect const& rect);
	t_window_clip_list& operator -= (t_clip_list const& regions);
	t_window_clip_list& operator += (t_window_rect const& rect);
	t_window_clip_list& operator += (t_window_clip_list const& regions);
protected:
	bool remove( t_screen_rect const& rect );   // internal support function for rect removal
	bool remove( t_clip_list const& regions );  // internal support function for region removal
	void update_extent();                       // force an extent recalculation

	t_screen_rect            m_extent;
	std::list<t_window_rect> m_rects;
};

inline t_window_clip_list::t_iterator t_window_clip_list::begin()
{
  return m_rects.begin();
}

inline t_window_clip_list::t_const_iterator t_window_clip_list::begin() const
{
  return m_rects.begin();
}

inline bool t_window_clip_list::empty() const
{
	return m_rects.empty();
}

inline t_window_clip_list::t_iterator t_window_clip_list::end()
{
  return m_rects.end();
}

inline t_window_clip_list::t_const_iterator t_window_clip_list::end() const
{
  return m_rects.end();
}

inline t_screen_rect const& t_window_clip_list::get_extent() const
{
  return m_extent;
}

inline bool contains( t_screen_rect const& rect, t_window_clip_list const& clip_list )
{
  return rect.contains( clip_list.get_extent() );
}

void subtract( t_clip_list& clip_list, t_window_clip_list const& window_list );

#endif // WINDOW_CLIP_LIST_H_INCLUDED